package jmine.tec.web.servlet.cipher.impl;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jmine.tec.utils.cripto.cipher.CipherInputStream;
import jmine.tec.utils.cripto.key.GeradorChaveRSA;
import jmine.tec.web.servlet.cipher.SecureCommunicationHandler;

/**
 * @author takeshi
 */
public class ExchangeKeysCommunicationHandler extends AbstractSecureCommunicationHandler {

    private final int chunkSize;

    private final transient PrivateKey localDecodeKey;

    private final transient Cipher cipher;

    /**
     * C'tor
     * 
     * @param decodeKeyToUse the {@link PrivateKey} use to decode the protocol
     * @param chunkSize int
     * @param cipher Cipher
     */
    public ExchangeKeysCommunicationHandler(PrivateKey decodeKeyToUse, int chunkSize, Cipher cipher) {
        this.chunkSize = chunkSize;
        this.localDecodeKey = decodeKeyToUse;
        this.cipher = GeradorChaveRSA.copyCipher(cipher);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SecureCommunicationHandler nextStage(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
        if (localDecodeKey == null || cipher == null) {
            return null;
        }
        try {
            CipherInputStream cin = new CipherInputStream(httpRequest.getInputStream(), cipher, localDecodeKey);
            PublicKey encoder = GeradorChaveRSA.leChavePublica(cin);
            return new SecureCommunicationHandlerImpl(encoder, localDecodeKey, chunkSize, cipher);
        } catch (InvalidKeyException e) {
            getLogger().warn("Cannot use the private key", e);
        } catch (InvalidKeySpecException e) {
            getLogger().warn("Cannot read remote public key", e);
        }
        return null;
    }

}
